﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CPPEI.ETL.Domain.Services
{
    public class BatchService
    {
        public void Save(EtlDbContext dbContext, string userId, Guid batchId, DateTime now, Entities.ETask eTask, List<Entities.EDtSourceParameter> eParameters,
            Dictionary<string, object> parameterValues)
        {
            using (EtlDbContext selfDbContext = new EtlDbContext())
            {
                EntityRepository<Entities.EBatch> bRep = new EntityRepository<Entities.EBatch>(selfDbContext);
                Entities.EBatch eBatch = new Entities.EBatch();
                eBatch.Id = batchId;
                eBatch.TaskId = eTask.Id;
                eBatch.DtSerId = eTask.DtSerId;
                eBatch.DtSourceId = eTask.DtSourceId;
                eBatch.Creator = userId;
                eBatch.CreatedTime = now;
                bRep.Create(eBatch);

                EntityRepository<Entities.EBatchParameter> bpRep = new EntityRepository<Entities.EBatchParameter>(selfDbContext);
                for (int index = 0; index < eParameters.Count; index++)
                {
                    Entities.EBatchParameter eBParameter = new Entities.EBatchParameter();
                    eBParameter.Id = Guid.NewGuid();
                    eBParameter.DtSerId = eTask.DtSerId;
                    eBParameter.DtSourceId = eTask.DtSourceId;
                    eBParameter.TaskId = eTask.Id;

                    object pValue = parameterValues[eParameters[index].Name];
                    if (pValue != null)
                    {
                        eBParameter.ValueString = pValue.ToString();
                    }
                    else
                    {
                        eBParameter.ValueString = null;
                    }

                    eBParameter.BatchId = eBatch.Id;
                    eBParameter.DtSourceParameterId = eParameters[index].Id;
                    eBParameter.Index = index;

                    bpRep.Create(eBParameter);
                }
                selfDbContext.SaveChanges();
            }
        }

        public ServiceResult<Models.MDtTableData> GetData(Guid batchId, int status, int start, int limit)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.EBatch> bRep = new EntityRepository<Entities.EBatch>(dbContext);
                Entities.EBatch eBatch = bRep.Get(p => p.Id == batchId);

                if (eBatch == null)
                {
                    return new ServiceResult<Models.MDtTableData>(false, ErrorCode.Batch_NotExist, ErrorCode.String(ErrorCode.Batch_NotExist));
                }

                EntityRepository<Entities.EDtSourceMapping> dsmRep = new EntityRepository<Entities.EDtSourceMapping>(dbContext);
                Entities.EDtSourceMapping eDtSourceMapping = dsmRep.Get(p => p.DtSourceId == eBatch.DtSourceId);

                EntityRepository<Entities.EDtTable> dtRep = new EntityRepository<Entities.EDtTable>(dbContext);
                Entities.EDtTable eTable = dtRep.Get(p => p.Id == eDtSourceMapping.DtTableId);

                if (eTable == null)
                {
                    Logger.ErrorToTag(Library.LogTAG, string.Format("BatchService.GetData出错,数据表为null,批次:{0}", batchId));
                    return new ServiceResult<Models.MDtTableData>(false, ErrorCode.NoMappintDtTable, ErrorCode.String(ErrorCode.NoMappintDtTable));
                }

                EntityRepository<Entities.EDtTableColumn> dtcRep = new EntityRepository<Entities.EDtTableColumn>(dbContext);
                List<Entities.EDtTableColumn> vDtColumns = dtcRep.GetList(p => p.DtTableId == eTable.Id);

                List<string> columns = new List<string>();
                for (int index = 0; index < vDtColumns.Count; index++)
                {
                    Entities.EDtTableColumn vDtColumn = vDtColumns[index];
                    columns.Add(vDtColumn.Name);
                }

                int total = 0;
                if (status != DEF.RawDataStatus.InsertSuccess)
                {
                    System.Data.DataTable dataTable = null;
                    using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["etl-db"].ConnectionString))
                    {
                        try
                        {
                            // 从缓存表里查询
                            dataTable = CPPEI.ETL.Domain.Util.DtTableUtil.GetPagedDataFromCacheTable(connection,
                                eTable.CacheName,
                                batchId,
                                status,
                                columns,
                                start,
                                limit,
                                out total);
                        }
                        catch (Exception ex)
                        {
                            return new ServiceResult<Models.MDtTableData>(false, ErrorCode.COM_DBError, ex.Message);
                        }
                        finally
                        {
                            if (connection.State == System.Data.ConnectionState.Open)
                            {
                                connection.Close();
                            }
                        }
                    }

                    Models.MDtTableData mDtTableData = new Models.MDtTableData(start, limit, total, dataTable);
                    return new ServiceResult<Models.MDtTableData>(true, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError), mDtTableData);
                }
                else
                {
                    if (string.Equals(eTable.Name, eTable.CacheName))
                    {
                        return new ServiceResult<Models.MDtTableData>(false, ErrorCode.DtTable_IsNotRawDataTable, ErrorCode.String(ErrorCode.DtTable_IsNotRawDataTable), null);
                    }

                    System.Data.DataTable dataTable = null;
                    using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["etl-db"].ConnectionString))
                    {
                        try
                        {
                            // 从真实数据表里查询
                            dataTable = CPPEI.ETL.Domain.Util.DtTableUtil.GetPagedDataFromCacheTable(connection,
                                eTable.CacheName,
                                batchId,
                                status,
                                columns,
                                start,
                                limit,
                                out total);
                        }
                        catch (Exception ex)
                        {
                            return new ServiceResult<Models.MDtTableData>(false, ErrorCode.COM_DBError, ex.Message);
                        }
                        finally
                        {
                            if (connection.State == System.Data.ConnectionState.Open)
                            {
                                connection.Close();
                            }
                        }
                    }

                    Models.MDtTableData mDtTableData = new Models.MDtTableData(start, limit, total, dataTable);
                    return new ServiceResult<Models.MDtTableData>(true, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError), mDtTableData);
                }
            }
        }

        public ServiceResult<Views.VBatchDetail> GetDetail(Guid batchId)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.EBatch> bRep = new EntityRepository<Entities.EBatch>(dbContext);
                EntityRepository<Entities.EBatchParameter> tpRep = new EntityRepository<Entities.EBatchParameter>(dbContext);
                EntityRepository<Entities.EDtSourceParameter> dspRep = new EntityRepository<Entities.EDtSourceParameter>(dbContext);
                Entities.EBatch eBatch = bRep.Get(p => p.Id == batchId);

                if (eBatch == null)
                {
                    return new ServiceResult<Views.VBatchDetail>(false, ErrorCode.Batch_NotExist, ErrorCode.String(ErrorCode.Batch_NotExist));
                }

                Views.VBatchDetail detail = new Views.VBatchDetail();
                detail.Batch = eBatch;

                detail.Parameters = tpRep.Query(p => p.BatchId == batchId).OrderBy(p => p.Index).ToList();
                detail.SourceParameters = dspRep.Query(p => p.DtSourceId == eBatch.DtSourceId).OrderBy(p => p.Index).ToList();

                return new ServiceResult<Views.VBatchDetail>(true, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError), detail);
            }
        }
    }
}
